package com.ym521.imgcrop.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.FloatRange;

import com.ym521.imgcrop.base.CropType;

/**
 * 矩形 切图
 */

public class RectCropView extends View implements CropFrame {
    protected float frameWidth;
    protected float frameHeight;
    protected float frameScale; //width/height
    protected float frameStrokeWidth;
    protected int frameStrokeColor;
    protected float mWidth;
    protected float mHeight;

    protected Paint paint;
    protected Path globalPath;
    protected Path framePath;
    protected PorterDuffXfermode xfermode;

    protected float widthRatio = 0.5f; //默认占比一半
    protected WHRatio whRatio = WHRatio.WH3_4; //切割框的宽高比

    public RectCropView(Context context) {
        this(context, null);
    }

    public RectCropView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RectCropView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    protected void init() {
        setClickable(false);
        xfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        globalPath = new Path();
        framePath = new Path();
        frameStrokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getContext().getResources().getDisplayMetrics());
        frameScale = whRatio.ration;
        frameStrokeColor = Color.WHITE;
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    public void setWidthRatio(@FloatRange(from = 0.1, to = 0.9) float widthRatio) {
        this.widthRatio = widthRatio;
        requestLayout();
    }

    public void setWhRatio(float whRatio) {
        frameScale = whRatio;
        Log.e("setWhRatio", "onClick()");
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.e("setWhRatio", "onMeasure()");
        mWidth = MeasureSpec.getSize(widthMeasureSpec);
        mHeight = MeasureSpec.getSize(heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawFrame();
        Log.e("setWhRatio", "onDraw()");
        //绘制整个画布的阴影
        canvas.translate(mWidth / 2, mHeight / 2);
        paint.setColor(Color.parseColor("#333333"));
        paint.setAlpha(255 / 3 * 2);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawPath(globalPath, paint);
        //擦除框内的阴影
        paint.setXfermode(xfermode);
        canvas.drawPath(framePath, paint);
        paint.setXfermode(null);
        //描出边框
        paint.setColor(frameStrokeColor);
        paint.setAlpha(255);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(frameStrokeWidth);
        canvas.drawPath(framePath, paint);
    }

    private void drawFrame() {
        int length = (int) Math.min(mWidth, mHeight);
        frameWidth = length * widthRatio;
        frameHeight = frameWidth / frameScale;
        globalPath.reset();
        globalPath.addRect(-mWidth / 2, -mHeight / 2, mWidth / 2, mHeight / 2, Path.Direction.CW);//顺时针
        framePath.reset();
        framePath.addRect(-frameWidth / 2, -frameHeight / 2, frameWidth / 2, frameHeight / 2, Path.Direction.CW);
    }


    @Override
    public CropType getCropType() {
        return CropType.RECT_CROP;
    }

    @Override
    public float getFrameScale() {
        return frameScale;
    }

    @Override
    public float getFrameWidth() {
        return frameWidth;
    }

    @Override
    public float getFrameHeight() {
        return frameHeight;
    }

    @Override
    public PointF getFramePosition() {
        float top = (mHeight - frameHeight) / 2;
        float left = (mWidth - frameWidth) / 2;
        return new PointF(left, top);
    }

    public enum WHRatio {
        WH1_1(1.0f), WH1_2(0.5f), WH2_1(2.0f), WH3_4(0.75f), WH4_3(4f / 3),
        WH16_9(16f / 9), WH9_16(9f / 16);
        private float ration;

        WHRatio(float ration) {
            this.ration = ration;
        }

        public float getRation() {
            return ration;
        }
    }
}
